package com.mybatisplus;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.*;

/**
 * @author zhangyalin@act-telecom.com
 * @date 2019-05-20 17:05
 **/
public class MybatisPlusGenteratorCode {

    private static String idType = "";
    private static String dbType = "mysql";
    private static String driver = "com.mysql.jdbc.Driver";
    private static String url = "";
    private static String username = "";
    private static String password = "";
    private static String author = "";
    private static String mapperSuffix = "Mapper";
    private static String mapperXmlSuffix = "Mapper";
    private static String serviceSuffix = "Service";
    private static String serviceImplSuffix = "ServiceImpl";
    private static String controllerSuffix = "Controller";
    private static String tablePrefix = "";
    private static String rootDir = "D:/MybatisGeneratorCode";
    private static String parentPackage = "java";
    private static String controllerPackage = "controller";
    private static String servicePackage = "service";
    private static String serviceImplPackage = "service.impl";
    private static String mapperPackage = "mapper";
    private static String entityPackage = "entity";
    private static String[] tables = {};

    private static IdType idtype = null;
    private static DbType databaseType = DbType.MYSQL;

    private static Logger logger = LoggerFactory.getLogger(MybatisPlusGenteratorCode.class);


    public static void main(String[] args) {

        if (args.length > 1) {
            if ("-configfile".equals(args[0].toLowerCase())) {
                String configFilePath = args[1];
                File configFile = new File(configFilePath);
                if (!configFile.exists()) {
                    URL resource = MybatisPlusGenteratorCode.class.getResource("");
                    configFile = new File(resource.getFile(), args[1]);
                }
                if (!configFile.exists()) {
                    logger.error("配置文件不存在！");
                } else {
                    Properties properties = new Properties();
                    try {
                        BufferedReader bufferedReader = new BufferedReader(new FileReader(configFile));
                        properties.load(bufferedReader);
                        setPropertiesValue(properties);

                        databaseType = DbType.getDbType(dbType);
                        if (StringUtils.isNoneBlank(idType)) {
                            idtype = IdType.valueOf(idType);
                        }
                        if (tables.length == 0) {
                            logger.error("没有指定数据库表！");
                        } else {
                            generatotCode();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            } else {
                logger.error("没有接收到期待的参数\"-configFile\"");
            }
        } else {
            logger.error("缺少参数！");
        }


    }

    private static void setPropertiesValue(Properties properties) {
        String idType_ = properties.getProperty("idType");
        String dbType_ = properties.getProperty("dbType");
        String driver_ = properties.getProperty("driver");
        String url_ = properties.getProperty("url");
        String username_ = properties.getProperty("username");
        String password_ = properties.getProperty("password");
        String author_ = properties.getProperty("author");
        String mapperSuffix_ = properties.getProperty("mapperSuffix");
        String mapperXmlSuffix_ = properties.getProperty("mapperXmlSuffix");
        String serviceSuffix_ = properties.getProperty("serviceSuffix");
        String serviceImplSuffix_ = properties.getProperty("serviceImplSuffix");
        String controllerSuffix_ = properties.getProperty("controllerSuffix");
        String tablePrefix_ = properties.getProperty("tablePrefix");
        String rootDir_ = properties.getProperty("rootDir");
        String parentPackage_ = properties.getProperty("parentPackage");
        String controllerPackage_ = properties.getProperty("controllerPackage");
        String servicePackage_ = properties.getProperty("servicePackage");
        String serviceImplPackage_ = properties.getProperty("serviceImplPackage");
        String mapperPackage_ = properties.getProperty("mapperPackage");
        String entityPackage_ = properties.getProperty("entityPackage");
        String tables_ = properties.getProperty("tables");

        if (StringUtils.isNotBlank(idType_)) {
            idType = idType_;
        }
        if (StringUtils.isNotBlank(dbType_)) {
            dbType = dbType_;
        }
        if (StringUtils.isNotBlank(driver_)) {
            driver = driver_;
        }
        if (StringUtils.isNotBlank(url_)) {
            url = url_;
        }
        if (StringUtils.isNotBlank(username_)) {
            username = username_;
        }
        if (StringUtils.isNotBlank(password_)) {
            password = password_;
        }
        if (StringUtils.isNotBlank(author_)) {
            author = author_;
        }
        if (StringUtils.isNotBlank(mapperSuffix_)) {
            mapperSuffix = mapperSuffix_;
        }
        if (StringUtils.isNotBlank(mapperXmlSuffix_)) {
            mapperXmlSuffix = mapperXmlSuffix_;
        }
        if (StringUtils.isNotBlank(serviceSuffix_)) {
            serviceSuffix = serviceSuffix_;
        }
        if (StringUtils.isNotBlank(serviceImplSuffix_)) {
            serviceImplSuffix = serviceImplSuffix_;
        }
        if (StringUtils.isNotBlank(controllerSuffix_)) {
            controllerSuffix = controllerSuffix_;
        }
        if (StringUtils.isNotBlank(tablePrefix_)) {
            tablePrefix = tablePrefix_;
        }
        if (StringUtils.isNotBlank(rootDir_)) {
            rootDir = rootDir_;
        }
        if (StringUtils.isNotBlank(parentPackage_)) {
            parentPackage = parentPackage_;
        }
        if (StringUtils.isNotBlank(controllerPackage_)) {
            controllerPackage = controllerPackage_;
        }
        if (StringUtils.isNotBlank(servicePackage_)) {
            servicePackage = servicePackage_;
        }
        if (StringUtils.isNotBlank(serviceImplPackage_)) {
            serviceImplPackage = serviceImplPackage_;
        }
        if (StringUtils.isNotBlank(mapperPackage_)) {
            mapperPackage = mapperPackage_;
        }
        if (StringUtils.isNotBlank(entityPackage_)) {
            entityPackage = entityPackage_;
        }
        if (StringUtils.isNotBlank(tables_)) {
            tables = tables_.trim().split(",");
            for (int i = 0; i < tables.length; i++) {
                tables[i] = tables[i].trim();
            }
        }
    }

    private static void generatotCode() {
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(databaseType)
                .setDriverName(driver)
                .setUrl(url)
                .setUsername(username)
                .setPassword(password);

        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(rootDir)
                .setFileOverride(true)
                .setActiveRecord(true)
                .setEnableCache(false)
                .setBaseResultMap(true)
                .setBaseColumnList(true)
                .setAuthor(author)
                .setEntityName("%s")
                .setMapperName("%s" + mapperSuffix)
                .setXmlName("%s" + mapperXmlSuffix)
                .setServiceName("%s" + serviceSuffix)
                .setServiceImplName("%s" + serviceImplSuffix)
                .setControllerName("%s" + controllerSuffix);
        if (idtype != null) {
            globalConfig.setIdType(idtype);
        }

        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setTablePrefix(tablePrefix)
                .setNaming(NamingStrategy.underline_to_camel)
                .setEntityTableFieldAnnotationEnable(true)
                .setInclude(tables);

        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent(parentPackage)
                .setController(controllerPackage)
                .setService(servicePackage)
                .setServiceImpl(serviceImplPackage)
                .setEntity(entityPackage)
                .setMapper(mapperPackage);

        InjectionConfig injectionConfig = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<>();
                map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-rb");
                this.setMap(map);
            }
        };
        //xml生成路径
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return rootDir + "/resources/" + tableInfo.getEntityName().replace("Entity", "") + mapperXmlSuffix + ".xml";
            }
        });
        injectionConfig.setFileOutConfigList(focList);

        // 关闭默认 xml 生成，调整生成 至 根目录
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setXml(null);

        AutoGenerator autoGenerator = new AutoGenerator();
        autoGenerator.setDataSource(dataSourceConfig)
                .setGlobalConfig(globalConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(packageConfig)
                .setCfg(injectionConfig)
                .setTemplate(templateConfig);

        autoGenerator.execute();
    }
}
